Try to use "some filenames except those that match this pattern" is a multi-step process in common shells. You have to generate the two lists of filenames, put those lists into separate files, then perform a "fgrep -v -f set2 set1" to get the list of files in the first set that are not in the second set.
setdiff is a small shell program for obtaining the difference of two sets of filenames. You use it by:
setdiff FIRSTSET SECONDSET
where FIRSTSET is a quoted glob for the first set of filenames, and SECONDSET is a quoted glob for the second set of filenames. (You can also use actual filename lists in place of the quoted globs.) For example, to get all files that are not C source or header files in your current directory, you would use:
setdiff '*' '*.h *.c'
which would print all filenames not ending in .h or .c to standard output.
A slightly more complicated example is finding out what files are not source code files in a project that is a mixture of Perl, C, and Java:
setdiff '*' '*.h *.c *.pl *.pm *.java'
A final example – find the XML files that are not XSL files (*.xml, *.xsd, etc.) mixed in with a bunch of source code files:
setdiff '/home/mycyc-0.22/*.x*' '/home/mycyc-0.22/*.xsl'
Here is the code:
#!/usr/bin/sh
# Output difference between two sets of filenames,
# i.e. the set difference of the the two filename sets.
# Names are assumed to be canonicalized already.
#
# This is the relative complement of B relative to A,
# also known as the set theoretic difference.
# Examples:
# { 1, 2, 4 } - { 1, 2, 5} = 4
# { 1, 2, 5 } - { 1, 2, 4} = 5
# check arguments
if [ "$1x" = "x" -o "$2x" = "x" ]; then
echo usage: setdiff FILESETEXPR1 FILESETEXPR2
exit 1
fi
# get a temporary filename for set #1
set1=`mktemp -t`
if [ "${set1}x" = "x" ]; then
echo "can't get temporary filename for set1"
exit 1
fi
# get a temporary filename for set #1
set2=`mktemp -t`
if [ "${set2}x" = "x" ]; then
echo "can't get temporary filename for set2"
exit 1
fi
# get the sets into temporary files
ls -1 $1 > $set1
ls -1 $2 > $set2
# compute all elements of set #1 not in set #2
fgrep -v -f $set2 $set1
By the way, setunion is setdiff, only with "fgrep -f $set1 $set2" at the end.
setdiff '*' '*.h *.c'
zsh!
Dom2 on 2006-02-17T22:31:13
I love zsh. It supports the korn shell globbing above as well as:% ls ^*.[ch]-Dom
comm -23 $set1 $set2
Also, you should probably add a line to delete those temp files:
That way, they get deleted on exit, or if some common signal gets delivered.trap "rm -f $set1 $set2" EXIT HUP INT QUITE TERM
-Dom